import React, { useState, memo, useEffect } from 'react';
import { Row, Col, Button, Form } from 'antd';
import styles from './index.less';
import classnames from 'classnames';
import Toolbar from '@/components/Toolbar';
import { ImportOutlined, SaveOutlined, ClearOutlined } from '@ant-design/icons';
import CodeMirror from './codeMirror.jsx';
import offset from 'document-offset';
import useModel from '../../useModel.js';
import IconFont from '@/components/IconFont';
import Connect from '@/components/Connect';
import { useUpdateEffect, useDebounceFn, usePersistFn, useUnmount, useMount } from '@umijs/hooks';

const ContextMenu = memo(props => {
  const {
    state: { editorDoc, contextMenuPosition, contextMenuVisible, placeHolderArray },
    placeHolderProps,
    setState,
  } = useModel(model => [
    model.state.contextMenuPosition,
    model.state.contextMenuVisible,
    model.state.editorDoc,
    model.state.placeHolderArray,
  ]);
  const handleVisibilityChange = e => {
    setState({ contextMenuVisible: false });
  };

  useUpdateEffect(() => {
    if (contextMenuVisible) {
      document.addEventListener('mousedown', handleVisibilityChange);
    } else {
      document.removeEventListener('mousedown', handleVisibilityChange);
    }
  }, [contextMenuVisible]);
  useMount(() => {
    placeHolderProps.run();
  });

  useUnmount(() => {
    document.removeEventListener('mousedown', handleVisibilityChange);
  });

  return (
    <>
      {contextMenuVisible && (
        <ul
          className={styles['context-menu']}
          style={{
            left: contextMenuPosition.left,
            display: contextMenuVisible ? 'block' : 'none',
            top: contextMenuPosition.top,
          }}
        >
          {!placeHolderArray[0] && <li>暂无数据</li>}
          {placeHolderArray[0] &&
            placeHolderArray.map((item, index) => {
              return (
                <li
                  key={index.toString(36) + index}
                  onMouseDown={e => {
                    e.stopPropagation();
                    // 阻止与原生事件的冒泡
                    e.nativeEvent.stopImmediatePropagation();
                  }}
                  onClick={e => {
                    // 阻止合成事件的冒泡
                    setState({ contextMenuVisible: false });
                    //替换
                    editorDoc.replaceSelection(item.name);
                  }}
                >
                  <Row>
                    <Col span={12} style={{ textAlign: 'left' }}>
                      {item.msg}
                    </Col>
                    <Col span={12} style={{ textAlign: 'left', color: 'red' }}>
                      {item.name}
                    </Col>
                  </Row>
                </li>
              );
            })}
        </ul>
      )}
    </>
  );
});
export default memo(() => {
  const {
    state: { message, msgType, messageName, selectedRow, isAddMode },
    format,
    save,
    run,
    setMessage,
    setState,
  } = useModel(model => [
    model.state.messageName,
    model.state.message,
    model.state.msgType,
    model.state.isAddMode,
    model.state.selectedRow,
  ]);
  const { run: changeMessageName } = useDebounceFn(value => {
    setState({ messageName: value });
  }, 500);

  let toolbar = [
    {
      type: 'button',
      name: '保存',
      htmlType: 'submit',
      theme: 'blue',
      icon: <IconFont type={'iconbaocun'} />,
      onClick: (e, form) => {
        const fields = form.getFieldsValue();
        setState({ ...fields });
        save(
          {
            ...fields,
            selectedRow,
            isAddMode,
          },
          run,
        );
      },
    },
    {
      type: 'button',
      name: '格式化',
      theme: 'white',
      icon: <IconFont type={'icongeshihua'} />,
      onClick: () => {
        format();
      },
    },
    {
      type: 'select',
      id: 'msgType',
      className: styles['device-type-select'],
      children: [
        { name: 'SU->SC', value: 0 },
        { name: 'SC->SU', value: 1 },
        { name: 'xml模板', value: 2 },
        { name: '信号点上报', value: 3 },
      ],
    },
    {
      type: 'inputItem',
      id: 'messageName',
      className: styles['message-wrap'],
      pos: 'right',
      name: '报文名称',
      onChange: e => {
        changeMessageName(e.target.value);
      },
    },
  ];

  return (
    <div className={styles['xml-edit-wrap']}>
      <Toolbar
        modules={toolbar}
        leftSpan={16}
        fields={{
          messageName,
          msgType,
        }}
        className={styles['toolbar-wrap']}
      />

      <div className={styles['xml-ct']}>
        <div className={styles['send']}>
          <div className={styles['title']}>
            <span>
              <span>请求报文内容</span>
              <span style={{ color: '#999', fontSize: '12px' }}>(右键可选择插入占位符)</span>
            </span>
          </div>
          <div className={styles['content']}>
            <CodeMirrorWrap
              code={message.sendMessage}
              onChange={code => {
                setMessage({ sendMessage: code });
              }}
            />
          </div>
        </div>

        <div className={styles['response']}>
          <div className={styles['title']}>
            <span>
              <span>响应报文内容</span>
              <span style={{ color: '#999', fontSize: '12px' }}>(右键可选择插入占位符)</span>
            </span>
          </div>
          <div className={styles['content']}>
            <CodeMirrorWrap
              code={message.responseMessage}
              onChange={code => {
                setMessage({ responseMessage: code });
              }}
            />
          </div>
        </div>
      </div>
      <ContextMenu />
    </div>
  );
});
//编辑器容器
const CodeMirrorWrap = memo(props => {
  const { code, onChange } = props;
  const {
    setState,
    state: { placeHolderArray },
  } = useModel(model => [model.state.placeHolderArray]);
  let asideWidth = 220;
  let headerHeight = 54;
  let margin = 20;

  const handleContextMenu = usePersistFn((Editor, e) => {
    let fix = offset(e.target);
    let offsetLeft = fix.left - asideWidth - margin;
    let offsetTop = fix.top - headerHeight - margin;
    let clientHeight = document.body.clientHeight;
    let top = e.clientY - fix.top + offsetTop;
    let autoHeight = placeHolderArray.length * 30;
    let contextMenuHeight = placeHolderArray.length * 30 > 310 ? 310 : autoHeight;
    if (clientHeight - e.clientY < contextMenuHeight) {
      top -= contextMenuHeight;
    }

    setState({
      contextMenuPosition: {
        left: e.clientX - fix.left + offsetLeft,
        top,
      },
      editorDoc: Editor.doc,
      contextMenuVisible: true,
    });
  });
  return <CodeMirror code={code} onContextmenu={handleContextMenu} onChange={onChange} />;
});
